#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mcheck.h>
#include "bib.h"

/** nome file lettura primo test */
#define FILE1 "./file_bib1"
/** nome file lettura secondo test */
#define FILE2 "./file_bib2"
/** nome file scrittura secondo test */
#define FILE2OUT "./file_bib2.out"
/** nome file scrittura terzo test */
#define FILE3OUT "./file_bib3.out"
/** nome controllo test sort*/
#define FILE4OUTCHECK "./file_bib4.out.check"
/** record ben formati del file FILE1 */
#define N_RECORD_FIRST_TEST 7
/** lunghezza max file di controllo */
#define LMAX 128


/** stampa tutte le schede nell'array su stdout
    \param s array da stampare
    \param n lunghezza dell'array
 */
static void stampa_schede (scheda_t** s, int n){
  int i;
  for (i=0; i<n; i++) {
    print_scheda(stdout,s[i]);
  }
}

/** libera la memoria occupata dall'array
    \param s array da stampare
    \param n lunghezza dell'array
 */
static void libera_schede (scheda_t** s, int n){
  int i;
  for (i=0; i<n; i++) {
    free_scheda(&s[i]);
  }
  free(s);
}

int main (void) {
  int n=0, nscritti;
  scheda_t** s = NULL, ** s2=NULL;
  FILE* out, *in;
  int i;
  char buf[LMAX];
  

  /* traccia la memoria allocata e deallocata */
  mtrace();

  /* test caricamento da file */
  /* apre il file */
  if ( ( in = fopen (FILE1, "r") ) == NULL ) {
    perror("fopen");
    exit(EXIT_FAILURE);
  }

  /* carica i record nell' array */
  if ( ( n=load_records(in,&s) ) != N_RECORD_FIRST_TEST ) {
    fprintf(stderr,"load_record: numero record ben formati errato\n");
    exit(EXIT_FAILURE);
  }

  fprintf(stdout,"Primo test: trovati %d record\n",n);
  stampa_schede(s,n);

  /* libera memoria */
  libera_schede(s,n);

  /* chiude il file */
  fclose(in);
  fprintf(stdout,"Fine primo test\n");

  /* test caricamento da file 2 */
  /* IN QUESTO CASO I RECORD SONO TUTTI CORRETTI */

  /* apre il file */
  if ( ( in = fopen (FILE2, "r") ) == NULL ) {
    perror("fopen");
    exit(EXIT_FAILURE);
  }

  /* carica i record */
  if ( (n=load_records(in,&s) ) <= 0 ) {
    perror("load_records");
    exit(EXIT_FAILURE);
  }

  fprintf(stdout,"Secondo test: trovati %d record\n",n);
  stampa_schede(s,n);


  /* scrive i record trovati su file */
  if ( ( out = fopen (FILE2OUT, "w") ) == NULL ) {
    perror("fopen");
    exit(EXIT_FAILURE);
  }


  if ( ( nscritti = store_records(out,s,n)) != n ) {
    fprintf(stdout,"Secondo test: scritti %d record\n",nscritti);
    exit(EXIT_FAILURE);
  } 

  /* dealloca array */  
  libera_schede(s,n);

  /* chiude i file */
  fclose(in);
  fclose(out);

  /* rilegge i record appena scritti e li converte di nuovo */
  if ( ( in = fopen (FILE2OUT, "r") ) == NULL ) {
    perror("fopen");
    exit(EXIT_FAILURE);
  }

  if ( (n=load_records(in,&s) ) <= 0 ) {
    perror("load_records");
    exit(EXIT_FAILURE);
  }

  /* nuovo file di out */
  if ( ( out = fopen (FILE3OUT, "w") ) == NULL ) {
    perror("fopen");
    exit(EXIT_FAILURE);
  }

 if ( ( nscritti = store_records(out,s,n)) != n ) {
    fprintf(stdout,"Terzo test: scritti %d record\n",nscritti);
    exit(EXIT_FAILURE);
  } 

 /* il makefile controlla a questo punto che i file FILE2OUT e FILE3OUT siano uguali */

 fclose(in);
 fclose(out);

 /* test del sort ... */
/*********** AUTORE ***************/

 if ( sort_schede (s,n,AUTORE) == -1 ){
   perror("sort_schede");
   exit(EXIT_FAILURE);
 } 
 
 /* apro file di controllo */
 sprintf(buf,"%s.%s",FILE4OUTCHECK,"autore");
 if ( ( in = fopen (buf, "r") ) == NULL ) {
    perror("fopen");
    exit(EXIT_FAILURE);
  }


 /* carico i record del file di controllo */
 if ( ( nscritti = load_records(in,&s2)) != n ) {
    fprintf(stdout,"autore: letti %d record\n",nscritti);
    exit(EXIT_FAILURE);
  } 

 /* controllo */
 for (i = 0; i < n; i++) {
   if ( ! is_equal_scheda(s[i],s2[i]) ){
       fprintf(stdout,"autore: scheda %d diversa ... \n",i);
	exit(EXIT_FAILURE);
     } 
 } 

 /* libero la memoria e chiudo il file */
 libera_schede(s2,n);
 fclose(in);
 
 /*********** TITOLO ***************/
 if ( sort_schede (s,n,TITOLO) == -1 ){
   perror("sort_schede");
   exit(EXIT_FAILURE);
 } 
 
 
 /* apro file di controllo */
 sprintf(buf,"%s.%s",FILE4OUTCHECK,"titolo");
 if ( ( in = fopen (buf, "r") ) == NULL ) {
    perror("fopen");
    exit(EXIT_FAILURE);
  }


 /* carico i record del file di controllo */
 if ( ( nscritti = load_records(in,&s2)) != n ) {
    fprintf(stdout,"autore: letti %d record\n",nscritti);
    exit(EXIT_FAILURE);
  } 

 /* controllo */
 for (i = 0; i < n; i++) {
   if ( ! is_equal_scheda(s[i],s2[i]) ){
       fprintf(stdout,"autore: scheda %d diversa ... \n",i);
	exit(EXIT_FAILURE);
     } 
 } 

 /* libero la memoria e chiudo il file */
 libera_schede(s2,n);
 fclose(in);

 
 
 /* libera memoria */
 libera_schede(s,n);

 /* fine traccia */
 muntrace();
 
 return EXIT_SUCCESS;
}
